.. _routes_develop: ###################################################### Руководство по разработке интеграционных маршрутов ###################################################### ******************************************************************** Назначение и описание. ******************************************************************** ======================================================================== Назначение ======================================================================== Частью приложения является интеграционный сервис, предназначеный для сопровождения логики, исполняемой на сервере приложения или интеграционном сервере. Интеграционный сервис приложения является модульным и расширяемым решением. Основой сервиса является **маршрут**. Маршрут - поток исполняемой логики, позволяющий описывать исполнение процесса обработки данных ("сообщений") или взаимодействие с внешними системами, такими как: * Веб сервисы * Базы данных * BMP системы * Очереди сообщений * и др.. | Интеграционные маршруты могут быть подключены как к запросам приложения к адаптерам, так и к ответам адаптеров на запросы. | Подключение маршрутов к запросам осуществляется с помощью маппинга маршрута к запросам системы к адаптерам (см: :numref:`routes_mapping`). | Список требуемых внешних маршрутов динамически строится в зависимости от схемы, метода и типа запроса. | Последовательность выполнения внешних маршрутов определяется приоритетом маршрута в маппинге. ======================================================================== Описание структуры маршрута ======================================================================== --------------------------------------------------------------------------- Элементы маршрута --------------------------------------------------------------------------- Маршрут состоит из следующих элементов: *Прием потока обработки данных (from)* | Элемент маршрута, описывающий начало маршрута, источник данных для получения данных. | По умолчанию данные поступают из бекенда, в ходе исполнения процесса пользователями. Bдентификатор маршрута, соответствует идентификатору маршрута в системе. *Передача потока обработки данных (to)* Элемент маршрута, описывающий передачу данных внешней системе или в другой маршрут обработки данных. *Процесс (process)* Элемент описывает использование интерфейса Processor для обработки данных в ветке потока обработки данных. *Java Bean (bean)* Элемент описывает использование JavaBean для обработки данных в ветке потока обработки данных. *Установка тела сообщения (setBody)* Элемент маршрута, позволяющий изменить тело сообщения (например сформировать запрос к внешней системе или изменить значение атрибутов для сохранения на адаптере. *Установка заголовка сообщения (setHeader)* Элемент маршрута, позволяющий установить заголовок сообщения *Удалить заголовок (removeHeader)* Элемент маршрута, позволяющий удалить заголовок сообщения *Удалить заголовки (removeHeaders)* Элемент маршрута, позволяющий удалить заголовки сообщения по шаблону *Преобразование (transform)* Элемент transform предназначен для трансформации тела сообщения (изменения значений атрибутов, изменения тела сообщения для передачи внешней системе. *Выбор (choice)* Элемент, позволяющий организовать ветвление в процессе обработки данных. *Условие (when)* Элемент, описывающий одну из веток ветвления потока обработки по условию. *Иначе (otherwise)* Элемент, описывающий альтернативную ветку потока, в случае, если условия ветвления не были выполнены. *Ошибка (onException)* Элемент маршрута, описывающий процесс обработки данных в случае появления ошибки. .. warning:: Классы JavaBeans и Processors, используемые в маршрутах должны быть размещены на сервере. Соответствующие им компоненты маршрута должны быть настроены в реестре компонентов (см: :numref:`registry_tune`). --------------------------------------------------------------------------- Описание маршрута в конфигурационной базе --------------------------------------------------------------------------- | Конфигурации маршрутов хранятся в формате JSON в таблице **ROUTE** конфигурационной базе приложения. | Параметры запуска внешнего маршрута, такие как схема, тип, метод, приоритет, а также статус и синхроность/ассинхроность, хранятся в таблице **ROUTE_MAPPING**. | Конфигурации компонентов реестра хранятся в таблице **ENDPOINTS**. Таблица ROUTE имеет следующие поля: * id – идентификатор маршрута; * tenant_id – идентификатор tenant; * definition – описание маршрута в формате JSON; * modify_date – дата последнего изменения маршрута; * status – статус маршрута. Данный параметр позволяет включать/отключать маршрут глобально в рамках данного приложения. Таблица ROUTE_MAPPING имеет следующие поля: * id – идентификатор маршрута; * tenant_id – идентификатор tenant; * schema_id – идентификатор схемы запроса; * method – метод запроса (GET, POST); * type – тип маршрута, определяющий принадлежность к преинтерсептору или постинтерсептеру ; * priority – приоритет маршрута в списке маршрутов данного запроса; * route_id – ссылка на описание маршрута в таблице ROUTE; * status – статус, позволяющий включать или отключать маршрут в рамках обработки для данного типа запроса; * async – параметр, определяющий синхронность/асинхронность выполнения маршрута. Таблица ENDPOINTS имеет следующие поля: * id– идентификатор компонента; * tenant_id – идентификатор tenant; * name - имя компонента; * type -тип компонента; * definition - описание компонента; * status - статус компонента; * modify_date – дата последнего изменения ; ======================================================================== Описание структуры сообщения ======================================================================== По маршруту обрабатываются сообщения. Сообщение состоит из: *Заголовки (Headers)* | Описываются параметры сообщения. | Параметры запроса к адаптеру описаны в заголовке **requestParams**. *Тело сообщения (Body)* | Описывается тело сообщения, например перечень атрибутов записи. **************************************************************************************************************************************** Правила формирования JSON описания маршрута. **************************************************************************************************************************************** ======================================================================== Структура JSON маршрута ======================================================================== JSON описание маршрута используется для построения XML описания на языке Apche Camel DSL. При этом JSON представляет собой усеченную версию описания маршрута, в которой отсутствуют некоторые атрибуты и вершины. Необходимые недостающие вершины автоматически добавляются в процессе трансляции из JSON в XML. Таким образом, процессе трансляции, к создаваемому внешнему маршруту будет добавлен аттрибут идентификатора маршрута, и вершина from, которые отсутствуют в JSON, но информация о которых приходит из Базы Данных при получении описания маршрута. JSON описание должно содержать всю необходимую информацию о маршруте, расположенную после вершины from. Пример JSON описания внешнего маршрута приведен ниже: :: {"route": [{"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This text1 added by async Enriching Route RT000000000000"}}, {"removeHeader":{"name":"RT000000000000"}}, {"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This text2 added by async Enriching Route RT000000000000"}}, {"setHeader":{"name":"currentTime", "type":"groovy", "value":"new java.util.Date().getTime()/1000"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"WARN","showHeaders":"true","showException":"false","showCaughtException":"false"}}}, {"to":{"uri":"sql:SELECT * FROM route_mapping?dataSource=#postgresSQL"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}, {"setBody":{"type":"constant", "value":"Test Body"}}, {"to":{"uri":"http://webservice:8080/wsdl/ExtSys_SAES2_MI.wsdl?httpMethod=GET"}}, {"transform":{"type":"simple", "value":"${body}"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"WARN","showHeaders":"true","showException":"false","showCaughtException":"false"}}}, {"choice":[ {"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] == null"}, {"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the route RT000000000000C1 condition 1"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}, {"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] != null"}, {"setHeader":{"name":"RT000000000000C1", "type":"constant", "value"="This header was added by the route RT000000000000C1 condition 2"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}, {"otherwise":[ {"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the route RT000000000000C1 condition otherwise"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}]}, {"onException": [ {"exception":"java.lang.NullPointerException"}, {"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This header was added by the exception handler"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"ERROR","showHeaders":"true","showException":"true","showCaughtException":"true"}}} ]} ] } .. .. note:: В теле маршрута можно передать XML описание маршрута, для этого XML должен быть преобразован в JSON строку. Тело запроса должно содержать только XML. Прмер такой строки приведен ниже: :: "........" .. JSON описание маршрута должно начинаться с корневого элемента “route”. Далее элемент “route” содержит список JSON компонентов, последовательность которых полностью определяет описание маршрута за исключением вершины from. :: {"route":[{элемент1:{набор параметров}, элемент2:{набор параметров}... элементN:{набор параметров}]} .. ======================================================================== Типовая структура элемента маршрута ======================================================================== Многие из элементов языка Spring DSL могут быть описаны объектом JSON, содержащей несколько ключевых параметров. В текущей версии приложения допускается использовать следующие не обязательные параметры: uri, options, ref, method. В свою очередь, параметр options, также должен содержать объект JSON состоящий из допустимых опций указанного элемента. В общем случае JSON формат описания типового элемента имеет следующий вид: :: {"name":{"uri":"url value","options":{"option1":"value1","option2":"value2",optionN":"valueN"},“ref”:”value”, “method”:”method_name”}} .. * name – имя элемента (обязательный параметр); * uri – uri (если необходимо для данного элемента); * options – список возможных опций элемента (если необходимо для данного элемента). В текущей версии данный параметр задает опции параметра uri; * ref – ссылка на другие элементы (если необходимо для данного элемента); * method – вызываемый метод (если необходимо для данного элемента). ======================================================================== Элемент to ======================================================================== Например, для элемента типа “to” описание в формате JSON может иметь следующий вид: :: {"to":{"uri":"direct:start"}}, {"to":{"uri":"sql:SELECT * FROM route_mapping?dataSource=#postgresSQL"}}, {"to":{"uri":"http://mgts-remedytst02:8080/wsdl/ExtSys_SAES2_MI.wsdl", "options":{"httpMethod":"GET"}}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}} .. ======================================================================== Элемент bean ======================================================================== Элемент “bean” может быть описан следующим образом: :: {"bean":{"ref":"testBean"}}, {"bean":{"ref":"testBean", "method":"removeComment"}}, {"bean":{"ref":"testBean", "method":"removeComment(${body}, ${headers})"}} .. ======================================================================== Элемент process ======================================================================== Элемент “process” можно описать так: :: {"process":{"ref":"testProcess"}} .. ======================================================================== Элемент setBody ======================================================================== Элемент setBody предназначен для установки нового значения тела сообщения. JSON формат этого элемента имеет следующую структуру: :: {"setBody":{"type":"способ указания значения тела", "value":"новое значение тела"}} .. Для указания значения тела сообщения могут быть применены разного рода конструкции, основанные на скриптовых языках (simple, spel, groovy) или просто константа (constant). Рассмотрим некоторые JSON примеры этого элемента. :: {"setBody":{"type":"constant", "value":"New Body"}}, {"setBody":{"type":"groovy", "value":"new java.util.Date().getTime()/1000"}}, {"setBody":{"type":"spel", "value":"#{request.body['-method'] “ } .. ======================================================================== Элемент setHeader ======================================================================== Элемент setHeader предназначен для установки значения заголовка сообщения. JSON формат данного элемента имеет следующую структуру: :: {"setHeader":{”name":"имя заголовка", "type":"способ указания значения заголовка", "value":"значение заголовка"}} .. Для указания значения заголовка могут быть применены разного рода конструкции, основанные на скриптовых языках (simple, spel, groovy) или просто константа (constant). Рассмотрим некоторые JSON примеры этого элемента. :: {"setHeader":{"name":"RT000000000000","type":"constant","value":"New Header"}}, {"setHeader":{"name":"RT000000000001","type":"groovy", "value":"new java.util.Date().getTime()/1000"}}, {"setHeader":{"name":"RT000000000002",""type":"spel", "value":"#{request.body['-method'] “ } .. ======================================================================== Элемент transform ======================================================================== Элемент transform предназначен для трансформации тела сообщения. JSON формат данного элемента имеет следующую структуру: :: {"transform":{"type":"тип правила трансформации", "value":"правило трансформации"}} .. Для указания значения типа правила трансформации могут быть применены разного рода конструкции, основанные на скриптовых языках (simple, spel, groovy). Рассмотрим некоторые JSON примеры этого элемента. :: {"transform":{"type":"simple", "value":"${body}"}}, {"transform":{"type":"spel", "value":"#{request.body}"}} .. .. ======================================================================== Элемент removeHeader ======================================================================== Элемент removeHeader предназначен для удаления заголовка сообщения. JSON формат данного элемента имеет следующую структуру: :: {"removeHeader":{"name":"имя заголовка"}} .. Рассмотрим JSON пример этого элемента. :: {"removeHeader":{"name":"RT000000000000"}} .. ======================================================================== Элемент removeHeaders ======================================================================== Элемент removeHeaders предназначен для удаления списка заголовков сообщения. JSON формат данного элемента имеет следующую структуру: :: {"removeHeaders":{"pattern":"шаблон имен для удаления","excludePattern":"шаблон имен для исключения удаления"}} .. Рассмотрим JSON пример этого элемента. :: {"removeHeaders":{"pattern":"*", "excludePattern":"Content-Type|Content-Length|MIME-Version"}} .. ======================================================================== Элементы choice и when ======================================================================== Элементы choice и when предназначены для организации ветвлений внутри маршрута. JSON формат для данного случая имеет следующую структуру: :: {"choice":[ {"when:[{"type":"тип условного выражения","condition":”условное выражение”},{элемент1}, {элемент2} … {элементN}]}, {"when:[{"type":"тип условного выражения","condition":”условное выражение”},{элемент1}, {элемент2} … {элементN}]}, {"when:[{"type":"тип условного выражения","condition":”условное выражение”},{элемент1}, {элемент2} … {элементN}]}, {"otherwise":[{элемент1}, {элемент2} … {элементN}]} ]} .. Рассмотрим JSON пример данной структуры. :: {"choice":[ {"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] == null"}, {"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the condition 1"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}, {"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] != null"}, {"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the condition 2"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}, {"otherwise":[ {"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by condition otherwise"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}]} .. ======================================================================== Элемент обработки исключения onException ======================================================================== Элемент onException используется для организации обработки исключения внутри маршрута. В каждом маршруте может присутствовать несколько секций обработки исключения. JSON формат для данного случая имеет следующую структуру: :: {"onException": [{"exception":"тип исключения"}, {элемент1}, {элемент2} … {элементN}]} Рассмотрим JSON пример данной структуры. :: {"onException": [ {"exception":"java.lang.NullPointerException"}, {"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This header was added by the exception handler"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"ERROR","showHeaders":"true","showException":"true","showCaughtException":"true"}}} ]} ******************************************************************** Примеры ******************************************************************** ======================================================================== Пример настройки компонента "SqlComponent" в реестре ======================================================================== :: { "driver": "org.postgresql.Driver", "username": "sa", "password": "123456", "url": "jdbc:h2:D:/var3/db/sgate;DB_CLOSE_DELAY=-1;TRACE_LEVEL_FILE=1;DATABASE_TO_UPPER=false;MODE=POSTGRES" } ..